﻿using Microsoft.VisualStudio.Modeling;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Project.Co_DataTransformationPrototype
{

    /// <summary>
    /// Represents the collection of events that have occured to a particular model element.
    /// Each type of event is store in a separate list.
    /// </summary>
    public class ElementEventInfo
    {
        // Events that pertain to an element
        public IList<EventContext> entityEvent;
        public IList<EventContext> attributeEvent;
        public IList<EventContext> linkEvent;

        // State of an element
        public StateBase entityState;
        public IDictionary<Guid, StateBase> entityAttributeState;

        // SQLCodeMapping
        //public MappingBase sqlMapping;

        /// Name property of the main entity
        public string MainEntityName { get; set; }

        public ElementEventInfo()
        {
            this.entityEvent = new List<EventContext>();
            this.attributeEvent = new List<EventContext>();
            this.linkEvent = new List<EventContext>();
            this.entityAttributeState = new Dictionary<Guid, StateBase>();
        }

        /// <summary>
        /// Collection of the SQL mappingsCollection of the SQL mappings
        /// </summary>
        /// <returns></returns>
        public string collectSQLStatements()
        {
            StringBuilder strbResult = new StringBuilder();

            var allSQLMappings = (from eContext in entityEvent
                                  where eContext.doSkipThisEvent == false
                                  select eContext.sqlEventMapping).Union(
                                  from eContext in attributeEvent
                                  where eContext.doSkipThisEvent == false
                                  select eContext.sqlEventMapping).Union(
                                  from eContext in linkEvent
                                  where eContext.doSkipThisEvent == false
                                  select eContext.sqlEventMapping);

            foreach (MappingBase sqlMapping in allSQLMappings)
                strbResult.Append(sqlMapping.GetSQLCodeMapping);

            return strbResult.ToString();
        }

        public override string ToString()
        {
            return MainEntityName;
        }
    }

    /// <summary>
    /// Context of a model event consisting of:
    /// action text, main entity's name, and an elementEventArgument object
    /// </summary>
    public class EventContext
    {
        public string actionText {get; set;}
        public string entityName { get; set; }
        public DateTime timestamp { get; set; }
        public bool doSkipThisEvent { get; set; }
        public MappingBase sqlEventMapping { get; set; }
        public ContextElementType elementType;
        public ElementEventArgs elementEventArgs;
    }

    public enum ContextElementType
    {
        Entity      = 1,
        Attribute   = 2,
        Link        = 3
    }

    /// <summary>
    /// Event argument class used to send event collection to the handler of this type of event
    /// </summary>
    public class ModelEventArgs : EventArgs
    {
        public IDictionary<Guid, ElementEventInfo> collection { get; set; }
    }

    /// <summary>
    /// Event argument class used to send sql mapping text to the handler of this type of event
    /// </summary>
    public class ScriptEventArgs : EventArgs
    {
        public StringBuilder scriptCollection{ get; set; }
    }

}
